/**
 * 悬停效果Hook
 *
 * 功能说明：
 * 1. 封装悬停效果的React Hook逻辑
 * 2. 提供鼠标事件处理和悬停状态管理
 * 3. 集成HoverManager进行悬停计算
 * 4. 提供Canvas渲染和状态检查方法
 * 5. 使用RAF优化性能，避免频繁重渲染
 *
 * 设计模式：自定义Hook + 性能优化
 */

import { useState, useCallback, useRef, useEffect } from 'react';
import { hoverManager, type HoverState } from '../utils/HoverManager';
import type { Room } from '../../../types/room';

// ========== Hook返回接口 ==========

/**
 * useHoverEffect Hook的返回接口
 * 定义Hook提供的所有方法和状态
 */
interface UseHoverEffectReturn {
  // ========== 悬停状态 ==========
  currentHover: HoverState | null; // 当前悬停状态

  // ========== 事件处理 ==========
  handleMouseMove: (event: React.MouseEvent<HTMLCanvasElement>) => void; // 鼠标移动处理
  handleMouseLeave: () => void; // 鼠标离开处理
  handleMouseEnter: () => void; // 鼠标进入处理

  // ========== 渲染函数 ==========
  renderHoverEffects: (ctx: CanvasRenderingContext2D) => void; // 渲染悬停效果
  getHoverInfo: () => string; // 获取悬停信息文本

  // ========== 状态检查 ==========
  isHoveringCell: (roomIndex: number, dateIndex: number) => boolean; // 检查是否悬停在指定单元格
  isHoveringRow: (roomIndex: number) => boolean; // 检查是否悬停在指定行
  isHoveringColumn: (dateIndex: number) => boolean; // 检查是否悬停在指定列
}

/**
 * 悬停效果Hook
 * 提供鼠标悬停时的交互效果和状态管理
 *
 * @param rooms 房间数据数组
 * @param dates 日期数据数组
 * @param config 甘特图配置对象
 * @returns 悬停效果相关的状态和方法
 */
export const useHoverEffect = (
  rooms: Room[],
  dates: string[],
  config: any
): UseHoverEffectReturn => {
  // ========== 状态管理 ==========

  /**
   * 当前悬停状态
   * 记录鼠标当前悬停的单元格信息
   */
  const [currentHover, setCurrentHover] = useState<HoverState | null>(null);

  /**
   * 悬停超时定时器引用
   * 用于延迟清除悬停状态
   */
  const hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  /**
   * 动画帧引用
   * 用于RAF优化，避免频繁重渲染
   */
  const rafRef = useRef<number | null>(null);

  /**
   * 上次悬停位置引用
   * 用于精细化防抖，只在跨越单元格边界时更新
   */
  const lastHoverRef = useRef<{ x: number; y: number } | null>(null);

  // ========== 初始化 ==========

  /**
   * 初始化悬停管理器
   * 当房间数据、日期数据或配置发生变化时重新初始化
   */
  useEffect(() => {
    hoverManager.initialize(rooms, dates, config);
  }, [rooms, dates, config]);

  // ========== 事件处理方法 ==========

  /**
   * 处理鼠标移动事件
   * 使用精细化防抖和RAF优化，只在跨越单元格边界时更新悬停状态
   * @param event 鼠标移动事件
   */
  const handleMouseMove = useCallback(
    (event: React.MouseEvent<HTMLCanvasElement>) => {
      const rect = event.currentTarget.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;

      // 精细化防抖：只在跨越单元格边界时更新
      const currentCellX = Math.floor(
        (x - config.roomTypeWidth - config.roomNumberWidth) / config.cellWidth
      );
      const currentCellY = Math.floor(y / config.cellHeight);

      // 检查是否还在同一个单元格内
      if (lastHoverRef.current) {
        const lastCellX = Math.floor(
          (lastHoverRef.current.x -
            config.roomTypeWidth -
            config.roomNumberWidth) /
            config.cellWidth
        );
        const lastCellY = Math.floor(
          lastHoverRef.current.y / config.cellHeight
        );

        // 如果还在同一个单元格内，不更新（性能优化）
        if (currentCellX === lastCellX && currentCellY === lastCellY) {
          return;
        }
      }

      // 记录当前位置
      lastHoverRef.current = { x, y };

      // 使用 requestAnimationFrame 优化性能
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current);
      }

      rafRef.current = requestAnimationFrame(() => {
        // 更新悬停状态
        const hoverState = hoverManager.updateHover(x, y);
        setCurrentHover(hoverState);

        // 调试日志
        if (hoverState) {
          console.log(
            `悬停: ${hoverManager.getHoverInfo()} (${hoverManager.getRelativeDateDescription(hoverState.date)})`
          );
        }
      });
    },
    [config]
  );

  /**
   * 处理鼠标离开事件
   * 清除所有悬停状态和定时器
   */
  const handleMouseLeave = useCallback(() => {
    // 清除悬停超时定时器
    if (hoverTimeoutRef.current) {
      clearTimeout(hoverTimeoutRef.current);
    }

    // 取消动画帧
    if (rafRef.current) {
      cancelAnimationFrame(rafRef.current);
    }

    // 清除悬停状态
    hoverManager.clearHover();
    setCurrentHover(null);
    lastHoverRef.current = null;
  }, []);

  /**
   * 处理鼠标进入事件
   * 鼠标进入甘特图区域时的初始化操作
   */
  const handleMouseEnter = useCallback(() => {
    // 鼠标进入时可以做一些初始化
    console.log('鼠标进入甘特图区域');
  }, []);

  // ========== 渲染方法 ==========

  /**
   * 渲染悬停效果
   * 在Canvas上绘制十字线高亮效果（行、列、单元格）
   * @param ctx Canvas 2D渲染上下文
   */
  const renderHoverEffects = useCallback(
    (ctx: CanvasRenderingContext2D) => {
      if (!currentHover) return;

      const crossHairConfig = hoverManager.getCrossHairConfig();

      // 保存当前绘制状态
      ctx.save();

      // 设置高亮样式
      ctx.globalAlpha = crossHairConfig.highlightOpacity;

      // 绘制行高亮 (整行高亮)
      if (crossHairConfig.showRowHighlight) {
        const rowArea = hoverManager.getRowHighlightArea();
        if (rowArea) {
          ctx.fillStyle = '#2196f3'; // 蓝色行高亮
          ctx.fillRect(rowArea.x, rowArea.y, rowArea.width, rowArea.height);
        }
      }

      // 绘制列高亮 (整列高亮)
      if (crossHairConfig.showColumnHighlight) {
        const columnArea = hoverManager.getColumnHighlightArea();
        if (columnArea) {
          ctx.fillStyle = '#4caf50'; // 绿色列高亮
          ctx.fillRect(
            columnArea.x,
            columnArea.y,
            columnArea.width,
            columnArea.height
          );
        }
      }

      // 绘制单元格高亮 (交叉点高亮)
      if (crossHairConfig.showCellHighlight) {
        const cellArea = hoverManager.getCellHighlightArea();
        if (cellArea) {
          ctx.globalAlpha = 0.3; // 单元格高亮更明显
          ctx.fillStyle = '#ff9800'; // 橙色单元格高亮
          ctx.fillRect(cellArea.x, cellArea.y, cellArea.width, cellArea.height);

          // 绘制高亮边框
          ctx.globalAlpha = 0.8;
          ctx.strokeStyle = '#ff5722';
          ctx.lineWidth = 2;
          ctx.strokeRect(
            cellArea.x,
            cellArea.y,
            cellArea.width,
            cellArea.height
          );
        }
      }

      // 恢复绘制状态
      ctx.restore();
    },
    [currentHover]
  );

  /**
   * 获取悬停信息文本
   * 生成悬停时显示的详细信息文本
   * @returns 悬停信息文本
   */
  const getHoverInfo = useCallback((): string => {
    if (!currentHover) return '';

    const room = rooms[currentHover.roomIndex];
    const hoverInfo = hoverManager.getHoverInfo();
    const relativeDate = hoverManager.getRelativeDateDescription(
      currentHover.date
    );

    return `${hoverInfo} - ${relativeDate} | ¥${room.price}/晚 | ${room.building} ${room.floor}楼`;
  }, [currentHover, rooms]);

  // ========== 状态检查方法 ==========

  /**
   * 检查是否悬停在指定单元格
   * @param roomIndex 房间行索引
   * @param dateIndex 日期列索引
   * @returns 是否悬停在该单元格
   */
  const isHoveringCell = useCallback(
    (roomIndex: number, dateIndex: number): boolean => {
      return hoverManager.isHoveringCell(roomIndex, dateIndex);
    },
    [currentHover]
  );

  /**
   * 检查是否悬停在指定行
   * @param roomIndex 房间行索引
   * @returns 是否悬停在该行
   */
  const isHoveringRow = useCallback(
    (roomIndex: number): boolean => {
      return hoverManager.isHoveringRow(roomIndex);
    },
    [currentHover]
  );

  /**
   * 检查是否悬停在指定列
   * @param dateIndex 日期列索引
   * @returns 是否悬停在该列
   */
  const isHoveringColumn = useCallback(
    (dateIndex: number): boolean => {
      return hoverManager.isHoveringColumn(dateIndex);
    },
    [currentHover]
  );

  // ========== 清理和返回 ==========

  /**
   * 清理定时器和动画帧
   * 组件卸载时清理所有定时器和动画帧，避免内存泄漏
   */
  useEffect(() => {
    return () => {
      if (hoverTimeoutRef.current) {
        clearTimeout(hoverTimeoutRef.current);
      }
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current);
      }
    };
  }, []);

  /**
   * 返回Hook的所有状态和方法
   */
  return {
    // 悬停状态
    currentHover,

    // 事件处理
    handleMouseMove,
    handleMouseLeave,
    handleMouseEnter,

    // 渲染方法
    renderHoverEffects,
    getHoverInfo,

    // 状态检查
    isHoveringCell,
    isHoveringRow,
    isHoveringColumn,
  };
};
